<!doctype html>
<html lang="en" class="page-type-section">
<head prefix="og: http://ogp.me/ns#">
<meta charset="utf-8">
<title>2.3.20 - FreeMarker 手册</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="format-detection" content="telephone=no">
<meta property="og:site_name" content="FreeMarker 手册">
<meta property="og:title" content="2.3.20">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="http://freemarker.org/docs/versions_2_3_20.html">
<link rel="canoical" href="http://freemarker.org/docs/versions_2_3_20.html">
<link rel="icon" href="favicon.png" type="image/png">
<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css">
</head>
<body itemscope itemtype="https://schema.org/Code">
    <meta itemprop="url" content="http://freemarker.org/docs/">
    <meta itemprop="name" content="FreeMarker 手册">

  <!--[if lte IE 9]>
  <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
  <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://freemarker.org" role="banner">            <img itemprop="image" src="logo.png" alt="FreeMarker">
</a><ul class="tabs"><li><a href="http://freemarker.org/">Home</a></li><li class="current"><a href="index.html">Manual</a></li><li><a class="external" href="http://freemarker.org/docs/api/index.html">Java API</a></li></ul><ul class="secondary-tabs"><li><a class="tab icon-heart" href="http://freemarker.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://sourceforge.net/p/freemarker/bugs/new/" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="http://freemarker.org/freemarkerdownload.html" title="Download"><span>Download</span></a></li></ul></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="toc.html" class="navigation-header">Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="toc.html"><span itemprop="name">FreeMarker 手册</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="app.html"><span itemprop="name">附录</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="app_versions.html"><span itemprop="name">版本历史</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="versions_2_3_20.html"><span itemprop="name">2.3.20</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><li><a href="alphaidx.html">Alpha. index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions</a></li><li><a href="ref_builtins_alphaidx.html">?builtins</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_specvar.html">.spec_vars</a></li><li><a href="app_faq.html">FAQ</a></li></ul></div></div></div>    <div class="main-content site-width">
      <div class="content-wrapper">
  <div id="table-of-contents-wrapper" class="col-left">
      <script>var breadcrumb = ["FreeMarker 手册","附录","版本历史","2.3.20"];</script>
      <script src="toc.js"></script>
      <script src="docgen-resources/main.min.js"></script>
  </div>
<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="versions_2_3_21.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3_19.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="versions_2_3_20" itemprop="headline">2.3.20</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#autoid_154" data-menu-target="autoid_154">Changes on the FTL side</a></li><li><a class="page-menu-link" href="#autoid_155" data-menu-target="autoid_155">Changes on the Java side</a></li><li><a class="page-menu-link" href="#autoid_156" data-menu-target="autoid_156">Other changes</a></li></ul> </div><p>Date of release: 2013-06-27</p><p>If you are IDE/tools author, <a href="#version_2_3_20_ide">note these changes</a>.</p>
          



<h2 class="content-header header-section2" id="autoid_154">Changes on the FTL side</h2>


          <ul>
            <li>
              <p>Error message quality improvements:</p>

              <ul>
                <li>
                  <p>Many error messages are now more helpful, especially
                  for users who are not experienced with FreeMarker. For
                  example, some of the most common user mistakes are
                  recognized and tips are shown to fix them, reducing support
                  costs or the time employees spend to figure them out.</p>
                </li>

                <li>
                  <p>It&#39;s now ensured that the error location in the
                  template is included in the message returned by
                  <code class="inline-code">TemplateException.getMessage()</code>. The stack
                  trace always showed this information anyway, but some users
                  only see the "message", not the stack trace,
                  and that often didn&#39;t contained the location.</p>
                </li>

                <li>
                  <p>The template language part of the stack trace is now
                  more detailed, and easier to understand. This is especially
                  helpful in applications that use a complex library of macros
                  and functions.</p>
                </li>

                <li>
                  <p>Several smaller bugs were fixed that made the error
                  information wrong or lacking.</p>
                </li>

                <li>
                  <p>The layout of the error messages is now more
                  consistent, and generally easier to read.</p>
                </li>
              </ul>
            </li>

            <li>
              <p>Changes regarding boolean to string conversions and
              formatting:</p>

              <ul>
                <li>
                  <p><code class="inline-code">?c</code> (computer-language formatting)
                  now works with booleans too, always giving
                  <code class="inline-code">&quot;true&quot;</code> or <code class="inline-code">&quot;false&quot;</code>
                  regardless of the <code class="inline-code">boolean_format</code>. This
                  way it&#39;s safe for generating JavaScript in a context where
                  human-readable text is also rendered.</p>
                </li>

                <li>
                  <p>If the <code class="inline-code">boolean_format</code> setting is
                  set to anything but the default
                  <code class="inline-code">&quot;true,false&quot;</code> value, boolean values will
                  be automatically converted to string where a string value is
                  expected by the template language, instead of giving an
                  error. This helps you spare
                  those<code class="inline-code">?string</code>-s after boolean values. This
                  is the same logic as with numbers and dates, which were
                  always automatically converted to string, according the
                  corresponding format setting. Except, the provided default
                  boolean format is useless for automatic conversion (but it&#39;s
                  still there for <code class="inline-code">?string</code>, for backward
                  compatibility), hence it must be set manually. (We certainly
                  couldn&#39;t come up with a sensible default anyway, as for
                  booleans it depends too much on the application, not to
                  mention the localisation issues.)</p>

                  <p>Exactly like with numbers and dates, automatic
                  conversion doesn&#39;t happen in these cases:</p>

                  <ul>
                    <li>
                      <p>Comparisons, i.e., <code class="inline-code">someBoolean ==
                      &#39;true&#39;</code> is still an error</p>
                    </li>

                    <li>
                      <p>Method calls where the declared type of the
                      parameter is <code class="inline-code">String</code> but the actual
                      value is a boolean; still an error</p>
                    </li>

                    <li>
                      <p>When the boolean value is used as key in
                      <code class="inline-code"><em class="code-color">expr</em>[<em class="code-color">key</em>]</code>,
                      it&#39;s still an error (there was no automatic conversion
                      there for other types either, as numerical and string
                      keys have different meaning)</p>
                    </li>

                    <li>
                      <p>The opposite direction, i.e., string to boolean
                      conversion; won&#39;t happen</p>
                    </li>
                  </ul>
                </li>
              </ul>
            </li>

            <li>
              <p>New built-ins for numbers: <a href="ref_builtins_number.html#ref_builtin_abs"><code>abs</code></a>, <a href="ref_builtins_number.html#ref_builtin_is_nan"><code>is_nan</code></a>,
              <a href="ref_builtins_number.html#ref_builtin_is_infinite"><code>is_infinite</code></a>.
              Like <code class="inline-code">n?abs</code> will give the absolute value of
              <code class="inline-code">n</code>.</p>
            </li>

            <li>
              <p>New built-in for sequences: <a href="ref_builtins_sequence.html#ref_builtin_join"><code>join</code></a>. Like
              <code class="inline-code">[1, 2, 3]?join(&quot;, &quot;)</code> will give the string
              <code class="inline-code">&quot;1, 2, 3&quot;</code>.</p>
            </li>

            <li>
              <p>If you set the
              <code class="inline-code">incompatible_improvements</code> setting (see <a href="http://freemarker.org/docs/api/freemarker/template/Configuration.html#setIncompatibleImprovements%28freemarker.core.Version%29">here</a>)
              to <code class="inline-code">2.3.20</code> or higher, <code class="inline-code">?html</code>
              will escape apostrophe-quotes just like
              <code class="inline-code">?xhtml</code> does. Utilizing this is highly
              recommended, because otherwise if interpolations are used inside
              attribute values that use apostrophe-quotation (<code class="inline-code">&lt;foo
              bar=&#39;${val}&#39;&gt;</code>) instead of plain quotation mark
              (<code class="inline-code">&lt;foo bar=&quot;${val}&quot;&gt;</code>), they might
              produce HTML/XML that&#39;s not well-formed. Note that
              <code class="inline-code">?html</code> didn&#39;t do this because long ago there
              was no cross-browser way of doing this, but it&#39;s not a real
              concern anymore. Also note that this will be the default
              behavior starting from 2.4.</p>
            </li>

            <li>
              <p>Bug fix [<a href="https://sourceforge.net/p/freemarker/bugs/390/">390</a>]
              (and other improvements): <code class="inline-code">?js_string</code> and
              <code class="inline-code">?json_string</code> didn&#39;t escape the
              <code class="inline-code">u2028</code>-<code class="inline-code">u2029</code> line
              terminators (problem for JavaScript) and the
              <code class="inline-code">u007F</code>-<code class="inline-code">u009F</code> control
              characters (maybe a problem in JSON, depending on
              implementation). Furthermore, the escaping of
              <code class="inline-code">\</code>, <code class="inline-code">&lt;</code>, and
              <code class="inline-code">&gt;</code> become safer in that now they are
              escaped whenever it can&#39;t be guaranteed that they won&#39;t be part
              of <code class="inline-code">&lt;!</code>, <code class="inline-code">]]&gt;</code> or
              <code class="inline-code">&lt;/</code>. Earlier they were only escaped when it
              was known that they are part of these patterns, thus it was
              possible to assemble these patterns from two adjacent
              interpolations. Additionally, from now on
              <code class="inline-code">&lt;?</code> and <code class="inline-code">--&gt;</code> also
              count as dangerous patterns, and will trigger
              <code class="inline-code">&lt;</code> and <code class="inline-code">&gt;</code>
              escaping.</p>
            </li>

            <li>
              <p>Bug fixed: The following string built-ins didn&#39;t coerce
              the numerical, date (and now the boolean) left-values to string,
              instead they threw a type error: contains,
              <code class="inline-code">index_of</code>, <code class="inline-code">last_index_of</code>,
              <code class="inline-code">left_pad</code>, <code class="inline-code">right_pad</code>,
              <code class="inline-code">matches</code>, <code class="inline-code">replace</code>,
              <code class="inline-code">split</code>, <code class="inline-code">new</code>. The other
              string built-ins already did this conversion for a long time;
              this was an accidental inconsistency.</p>
            </li>

            <li>
              <p>Bug fixed: With the default arithmetic engine, it&#39;s now
              supported to compare infinite (positive or negative) with 0, to
              decide its sign.</p>
            </li>
          </ul>
        
          



<h2 class="content-header header-section2" id="autoid_155">Changes on the Java side</h2>


          <ul>
            <li>
              <p><code class="inline-code">BeansWrapper</code> introspection cache
              improvements:</p>

              <ul>
                <li>
                  <p>Added public API to <code class="inline-code">BeansWrapper</code>
                  for clearing the class cache:
                  <code class="inline-code">clearClassIntrospecitonCache()</code>,
                  <code class="inline-code">removeFromClassIntrospectionCache(Class)</code></p>
                </li>

                <li>
                  <p>Significantly improved multi-core performance:</p>

                  <ul>
                    <li>
                      <p>Uses <code class="inline-code">ConcurrentHashMap</code> when
                      running on Java 5 or later.</p>
                    </li>

                    <li>
                      <p>The cache won&#39;t block readers while introspecting
                      a class after a cache miss</p>
                    </li>

                    <li>
                      <p>If multiple threads need to introspect the same
                      class that&#39;s not in the cache yet, only one of them will
                      do it, the others will wait for its results.</p>
                    </li>
                  </ul>
                </li>

                <li>
                  <p>Bug fix [<a href="https://sourceforge.net/p/freemarker/bugs/361/">361</a>]:
                  There was a small chance of deadlock when class-reloading
                  was detected. Locking was redesigned to prevent such
                  oversights in the future.</p>
                </li>

                <li>
                  <p>The internal package-visible
                  <code class="inline-code">freemarker.ext.beans</code> API was slightly
                  changed as the result of internal cleanup. Nobody but the
                  FreeMarker developers should define classes in that package,
                  so it shouldn&#39;t break anything. But if somebody did some
                  in-house hacks there, re-compile to see if it still
                  works.</p>
                </li>
              </ul>
            </li>

            <li>
              <p>Nameless templates (those directly created with
              <code class="inline-code">new Template(null,
              <em class="code-color">...</em>)</code> instead of loaded
              through <code class="inline-code">Configuration</code>) couldn&#39;t include or
              import other templates, and thrown a
              <code class="inline-code">NullPointerException</code> when they tried to. Now
              they resolve relative paths as if they were in the template root
              directory.</p>
            </li>

            <li>
              <p>Bug fix: Regular expression built-ins and some logger
              libraries (most importantly Log4J) were unavailable on the
              Google App Engine platform. This fix is only present in the
              GAE-compatible build, 2.3.20-gae.</p>
            </li>

            <li>
              <p>Added new method to <code class="inline-code">Configuration</code>:
              <code class="inline-code">CacheStorage getCacheStorage()</code></p>
            </li>

            <li>
              <p>Added new methods to <code class="inline-code">Environment</code> to
              make comparisons among <code class="inline-code">TemplateModel</code>-s
              according the rules of the template language operators:
              <code class="inline-code">applyEqualsOperator</code>,
              <code class="inline-code">applyEqualsOperatorLenient</code>,
              <code class="inline-code">applyLessThanOperator</code>,
              <code class="inline-code">applyLessThanOrEqualsOperator</code>,
              <code class="inline-code">applyGreaterThanOperator</code>,
              <code class="inline-code">applyWithGreaterThanOrEqualsOperator</code></p>
            </li>

            <li>
              <p>Added new method,
              <code class="inline-code">Environment.isInAttemptBlock()</code> to check if we
              are within an <code class="inline-code">#attempt</code> block. This can be
              useful for <code class="inline-code">TemplateExceptionHandler</code>-s, as
              then they don&#39;t need to print the error to the output since
              <code class="inline-code">#attempt</code> will roll it back anyway. This is
              already utilized by the built-in
              <code class="inline-code">TemplateExceptionHandler</code>-s
              (<code class="inline-code">DEBUG_HANDLER</code> and
              <code class="inline-code">HTML_DEBUG_HANDLER</code>).</p>
            </li>

            <li>
              <p>Added convenience constructor <code class="inline-code">Template(String
              name, String sourceCode, Configuration cfg)</code>.</p>
            </li>

            <li>
              <p><code class="inline-code">TemplateException</code>-s and
              <code class="inline-code">TemplateModelExcepton</code>-s now can have
              <code class="inline-code">Throwable</code> cause, not just
              <code class="inline-code">Exception</code> (it was an old oversight that
              somehow wasn&#39;t fixed so far).</p>
            </li>

            <li>
              <p>Parsing error messages under the JBoss Tools FreeMarker
              IDE now doesn&#39;t contain the usual location line, so that the
              actual error description is immediately visible in the Eclipse
              "Problems" view. (It&#39;s a "hack" in
              FreeMarler itself; it tries to detect if it runs under the
              plugin and then changes its behavior.)</p>
            </li>

            <li>
              <p><a name="version_2_3_20_ide"></a>Mostly concerning tool (like IDE plugin) authors:</p>

              <ul>
                <li>
                  <p>The error message formats (what
                  <code class="inline-code">Throwable.getMessage()</code> returns) were
                  heavily changed for <code class="inline-code">TemplateException</code>-s,
                  and somewhat for <code class="inline-code">ParseException</code>-s. It&#39;s
                  unlikely that anybody depends on these, but if you tried to
                  parse these messages, be aware of this.</p>
                </li>

                <li>
                  <p>Fixed bug where <code class="inline-code">ParseException</code> has
                  contained 0 as line and column number for lexical errors.
                  Now it contains the correct information.</p>
                </li>

                <li>
                  <p>Added
                  <code class="inline-code">ParseException.getEditorMessage()</code>: As in
                  IDE-s the error markers show the error location to the user
                  already, the location should not be repeated in the error
                  message. So in IDE-s you should use this method instead of
                  <code class="inline-code">getMessage()</code>. (Under JBoss Tools:
                  FreeMarker now <em>tries</em> to detect that it
                  runs under the plugin, and then it already does this, except
                  that it still shows the column number as that&#39;s missing from
                  the error marker location.)</p>
                </li>

                <li>
                  <p>Added
                  <code class="inline-code">ParseException.getTemplateName()</code></p>
                </li>

                <li>
                  <p>Added
                  <code class="inline-code">Configuration.getSupportedBuiltInNames()</code>.
                  As new built-ins
                  (<code class="inline-code"><em class="code-color">expr</em>?<em class="code-color">builtin_name</em></code>)
                  are very often added to new FreeMarker versions,
                  auto-completion or syntax highlighting should use this set
                  instead of a fixed set of a names.</p>
                </li>

                <li>
                  <p>The format returned by
                  <code class="inline-code">TemplateElement.getDescription()</code> was
                  heavily changed. It&#39;s what FTL stack traces and maybe some
                  outline views (tree-views) show. It was always for human
                  reading (and till now was too inconsistent for anything
                  else), so it&#39;s unlikely that this breaks anything.</p>
                </li>

                <li>
                  <p>There were some smaller changes in
                  <code class="inline-code">freemarker.debug</code>, and it&#39;s expected that
                  there will be more, so it was marked as experimental. As far
                  as we know, nobody used it, so it shouldn&#39;t break
                  anything.</p>
                </li>
              </ul>
            </li>

            <li>
              <p>In <em>experimental status only</em>, but
              <code class="inline-code">freemarker.jar</code> is now an OSGi bundle (see
              <code class="inline-code">freemarker.jar/META-INF/MANIFEST.MF</code>).
              Depending on user feedback, the bundle description may change in
              the future. So please give feedback, especially if you are an
              OSGi expert!</p>
            </li>

            <li>
              <p>Improved the HTML generated by
              <code class="inline-code">HTML_DEBUG_HANDLER</code> (the
              red-on-yellow-background error message). Most importantly, now
              it will word-wrap. Other changes are minor, like now it can
              break out of CDATA sections, or now it has less intense
              colors.</p>
            </li>

            <li>
              <p>New <code class="inline-code">Template</code> method,
              <code class="inline-code">getActualTagSyntax()</code>: Tells if the template
              is using traditional or square-bracket syntax. As the syntax can
              be overridden in the template, also it&#39;s possibly decided by
              auto-detection, it wasn&#39;t trivial to it tell till now.</p>
            </li>

            <li>
              <p>Added some utility methods that are useful for generating
              error messages in custom directives:
              <code class="inline-code">ClassUtil.getFTLTypeDescription(TemplateModel)</code>,
              <code class="inline-code">getShortClassName</code>,
              <code class="inline-code">getShortClassNameOfObject</code></p>
            </li>

            <li>
              <p>Bug fix [<a href="https://sourceforge.net/p/freemarker/bugs/364/">364</a>]:
              <code class="inline-code">freemarker.template.EmptyMap</code> (which is passed
              to <code class="inline-code">TemplateDirectiveModel</code>-s if there are no
              parameters) now allows <code class="inline-code">remove(key)</code>,
              <code class="inline-code">clear()</code> and
              <code class="inline-code">putAll(anyEmptyMap)</code> as these do nothing
              anyway.</p>
            </li>

            <li>
              <p>Bug fix [<a href="https://sourceforge.net/p/freemarker/bugs/375/">375</a>]:
              <code class="inline-code">NullPointerException</code> on IBM J9 VM (not on the
              Sun/Oracle implementation) in <code class="inline-code">BeansWrapper</code>
              when the Java implementation legally returns
              <code class="inline-code">null</code> for some <code class="inline-code">BeanInfo</code>
              getters.</p>
            </li>

            <li>
              <p>Bug fix: Cloning a <code class="inline-code">Configuration</code> didn&#39;t
              deep-clone the data structures storing the
              <code class="inline-code">auto_imports</code> and
              <code class="inline-code">auto_includes</code> settings, hence possibly
              leading to aliasing problems.</p>
            </li>

            <li>
              <p>Bug fix [<a href="https://sourceforge.net/p/freemarker/bugs/377/">377</a>]:
              After a failed method call the exception handler could fail in
              the rare occasion when
              <code class="inline-code">targetObject.toString()</code> fails, raising a
              runtime exception that not even the <code class="inline-code">attempt</code>
              directive will catch.</p>
            </li>

            <li>
              <p>Bug fix [<a href="https://sourceforge.net/p/freemarker/bugs/391/">391</a>]:
              If a template name has contained <code class="inline-code">*</code> that was
              not the only character in the path step, it threw
              <code class="inline-code">NegativeArraySizeException</code> instead of
              <code class="inline-code">FileNotFoundException</code>.</p>
            </li>

            <li>
              <p>With the default arithmetic engine, performance
              optimizations of comparison operations when some of the numbers
              is 0, and when the sign of the numbers differ.</p>
            </li>

            <li>
              <p>Some smaller fixes in
              <code class="inline-code">TemplateElement.getCanonicalForm()</code>, also some
              quality improvements there.</p>
            </li>

            <li>
              <p>Bug fixes in <code class="inline-code">classic_compatible</code> mode
              (this mode is to help migrating from FreeMarker 1), thanks to
              Information Mosaic:</p>

              <ul>
                <li>
                  <p>When a macro was called with a
                  <code class="inline-code">null</code>/missing parameter value, it has
                  caused error like in FreeMarker 2.3</p>
                </li>

                <li>
                  <p>When a hash literal contained reference to a
                  <code class="inline-code">null</code>/missing variable, like in <code class="inline-code">{
                  &#39;a&#39;: missingVar }</code>, it has caused an error like in
                  2.3</p>
                </li>

                <li>
                  <p>When a sequence literal contained reference to a
                  <code class="inline-code">null</code>/missing variable, like in
                  <code class="inline-code">[1, missingVar]</code>, it has caused an error
                  like in 2.3</p>
                </li>

                <li>
                  <p>When a the left-side of the <code class="inline-code">.</code> (dot)
                  or <code class="inline-code">[<em class="code-color">key</em>]</code>
                  operator was <code class="inline-code">null</code> or missing variable,
                  like in <code class="inline-code">missingVar.subVar</code>, it has caused
                  an error like in 2.3</p>
                </li>

                <li>
                  <p>When <code class="inline-code">BeanModel</code>-s are tried to be
                  treated as strings, for most subclasses it has failed with
                  type error, like in 2.3. In FreeMarker 1 all
                  <code class="inline-code">BeanModel</code>-s were
                  <code class="inline-code">TemplateScalarModel</code>-s, so it should
                  succeed. The fix for this only works where FreeMarker
                  <em>coerces</em> to string (string built-ins on
                  the left-side and concatenation (<code class="inline-code">+</code>) and
                  interpolation
                  (<code class="inline-code">${<em class="code-color">...</em>}</code>) do
                  that), otherwise unfortunately it will still fail.</p>
                </li>

                <li>
                  <p>The <code class="inline-code">classic_compatible</code> setting now
                  accepts value <code class="inline-code">2</code> along
                  <code class="inline-code">true</code> (alias <code class="inline-code">1</code>) and
                  <code class="inline-code">false</code> (alias <code class="inline-code">0</code>).
                  <code class="inline-code">2</code> means <code class="inline-code">true</code> but with
                  emulating bugs in early 2.x classic-compatibility mode.
                  Currently this only affects how booleans are converted to
                  string; with <code class="inline-code">1</code> it&#39;s always
                  <code class="inline-code">&quot;true&quot;</code>/<code class="inline-code">&quot;&quot;</code>, but with
                  <code class="inline-code">2</code> it&#39;s <code class="inline-code">&quot;true&quot;/&quot;false&quot;</code>
                  for values wrapped by <code class="inline-code">BeansWrapper</code> as
                  then <code class="inline-code">Boolean.toString()</code> prevails. Note
                  that
                  <code class="inline-code"><em class="code-color">someBoolean</em>?string</code>
                  will always consistently format the boolean according the
                  <code class="inline-code">boolean_format</code> setting, just like in
                  FreeMarker 2.3.</p>
                </li>
              </ul>
            </li>

            <li>
              <p>Bug fix [<a href="https://sourceforge.net/p/freemarker/bugs/394/">394</a>]:
              When trying to access the optional Jython (or W3C DOM) classes
              has failed in <code class="inline-code">DefaultObjectWrapper</code> with an
              <code class="inline-code">Error</code>, rather than with an
              <code class="inline-code">Exception</code>, loading the
              <code class="inline-code">DefaultObjectWrapper</code> class itself has failed,
              instead of the Jython (or W3C DOM) support being disabled. From
              now in, it will survive any kind of <code class="inline-code">Throwable</code>
              there, and if the <code class="inline-code">Throwable</code> is not an
              <code class="inline-code">ClassNotFoundException</code>, it will also log the
              <code class="inline-code">Throwable</code>.</p>
            </li>

            <li>
              <p>Improved the performance of
              <code class="inline-code">(thisVarIsMissing.foo)!default</code> and similar
              <em>parenthetical</em> existence operators and
              existence built-ins in the case when the
              <code class="inline-code">null</code>/missing variable is not the last step
              inside the parenthesis. In that case it&#39;s about 30 times faster
              now, measured on Java 6. In other cases (when all variables
              exists, or the the last step is missing) the performance is
              about the same (relatively fast) as before.</p>
            </li>

            <li>
              <p>Added interface
              <code class="inline-code">freemarker.cache.CacheStorageWithGetSize</code>
              which allows querying the current number of cache entries in a
              <code class="inline-code">CacheStorage</code> that implements it. It&#39;s
              implemented by all out-of-the-box
              <code class="inline-code">CacheStorage</code> implementations. Also added
              <code class="inline-code">getStrongSize()</code> and
              <code class="inline-code">getSoftSize()</code> to
              <code class="inline-code">MRUCacheStorage</code>.</p>
            </li>

            <li>
              <p>Version and build information changes:</p>

              <ul>
                <li>
                  <p>The form of the nightly build version numbers has
                  changed to be Maven/JSR 277 compliant. What earlier was
                  <code class="inline-code">2.3.19mod</code> is now something like
                  <code class="inline-code">2.3.20-nightly_20130605T130506Z</code> (note how
                  the last points to the target release version instead of the
                  last release version).</p>
                </li>

                <li>
                  <p>The form of the Release Candidate and Preview version
                  numbers where changed to be Maven/JSP 277 compliant:
                  <code class="inline-code">2.4pre2</code> is now
                  <code class="inline-code">2.4.0-pre02</code>, <code class="inline-code">2.4rc1</code> is
                  now <code class="inline-code">2.4.0-rc01</code>.</p>
                </li>

                <li>
                  <p>Added new static method to
                  <code class="inline-code">Configuration</code> to query build date:
                  <code class="inline-code">getBuildDate()</code>. This is also printed by
                  the main command line class.</p>
                </li>
              </ul>
            </li>

            <li>
              <p>Various internal code cleanups.</p>
            </li>
          </ul>
        
          



<h2 class="content-header header-section2" id="autoid_156">Other changes</h2>


          <ul>
            <li>
              <p>Many JavaDoc improvements, mostly in the documentation of
              the basic (most frequently used) classes.</p>
            </li>

            <li>
              <p>FreeMarker source code has moved to GitHub (<a href="???">https://github.com/freemarker/freemarker</a>),
              other project resources has remained on sourceforge.net.</p>
            </li>

            <li>
              <p>Project structure cleanup, Ivy-based build script.</p>
            </li>
          </ul>
        <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="versions_2_3_21.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3_19.html"><span>Next</span></a></div></div></div></div>      </div>
    </div>
<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"><div class="column"><h3 class="column-header">Overview</h3><ul><li><a href="http://freemarker.org/index.html">What is FreeMarker?</a></li><li><a href="http://freemarker.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="http://freemarker.org/history.html">About us</a></li><li><a itemprop="license" href="app_license.html">License</a></li></ul></div><div class="column"><h3 class="column-header">Handy stuff</h3><ul><li><a href="http://freemarker-online.kenshoo.com/">Try template online</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions cheatsheet</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_builtins_alphaidx.html">?built_ins</a></li><li><a href="ref_specvar.html">.special_vars</a></li></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href="https://github.com/nanlei/freemarker/tree/manual-zh-2.3-gae/src/manual">Chinese Manual on Github</a></li><li><a href="https://github.com/freemarker/freemarker">FreeMarker on Github</a></li><li><a href="https://twitter.com/freemarker">Follow us on Twitter</a></li><li><a href="https://sourceforge.net/p/freemarker/bugs/new/">Report a bug</a></li><li><a href="http://stackoverflow.com/questions/ask?tags=freemarker">Ask a question</a></li><li><a href="http://freemarker.org/mailing-lists.html">Mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/freemarker/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="http://stackoverflow.com/questions/ask?tags=freemarker">Stack Overflow</a></li></ul><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"><p><span class="generated-for-product">Generated for: Freemarker 2.3.23</span><span class="last-updated"> Last generated:
<time itemprop="dateModified" datetime="2015-09-18T14:38:51Z" title="Friday, September 18, 2015 2:38:51 PM GMT">2015-09-18 14:38:51 GMT</time></span></p> <p class="copyright">
© <span itemprop="copyrightYear">1999</span>–2015
<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="http://freemarker.org">The FreeMarker Project</a>. All rights reserved. </p>
</div></div></div></body>
</html>
